#pragma once

#include <glm/glm.hpp>
#include "teflon/core/events.h"


namespace teflon
{
    struct Camera2D
    {
    private:
        glm::vec2 pos;
        float rotation;
        float scale;
    public:
        Camera2D();

        glm::mat4 getProjectionMatrix() const { return glm::mat4(1.0f); }
        glm::mat4 getViewMatrix() const;

        void zoom(float dz);
        void move(float dx, float dy);
        void rotate(float dt);

        void zoomTo(float scale);
        void moveTo(float x, float y);
        void rotateTo(float angle);

    private:
        // static bool on_key_pressed(EventType eventType, void* sender, void* listener, void* context);
    };

    struct Camera3D
    {
    private:
        float pitch;
        float yaw;

        glm::vec3 pos;
        glm::vec3 up;
        glm::vec3 worldUp;

    public:
        Camera3D(const glm::vec3& pos = glm::vec3(0.0f, 0.0f, 0.0f), float yaw = 0.0f, float pitch = 0.0f);
        glm::mat4 getProjectionMatrix(uint32_t width, uint32_t height) const;
        glm::mat4 getViewMatrix() const;
        glm::mat4 getViewMatrixOrigin() const;

        void translate(float dx, float dy, float dz);
        void rotate(float dyaw, float dpitch);

        void moveTo(float x, float y, float z);
        void pointTo(float x, float y, float z);
        void moveTo(const glm::vec3& p) { moveTo(p.x, p.y, p.z); }
        void pointTo(const glm::vec3& p) { pointTo(p.x, p.y, p.z); }

        void SetYaw(float y) { yaw = y; }
        void SetPitch(float p) { pitch = p; }

    private:
        glm::vec3 getFrontVector() const;
        void updateVectors();
        // static bool on_key_pressed(EventType type, void* sender, void* listener, void* context);
    };

}


